﻿using Castle.Core.Logging;
using System;

namespace Basefr.Logging.NLogExtensions
{
    [Serializable]
    public class NLogLogger : MarshalByRefObject, IExtendedLogger
    {
        private readonly NLog.ILogger _logger;

        public NLogLogger(NLog.ILogger logger)
        {
            _logger = logger;
        }

        private NLogLogger()
        {
        }

        public NLog.ILogger Instance => _logger;


        public IContextProperties GlobalProperties => throw new NotImplementedException();
        public IContextProperties ThreadProperties => throw new NotImplementedException();
        public IContextStacks ThreadStacks => throw new NotImplementedException();


        public bool IsDebugEnabled => _logger.IsDebugEnabled;
        public bool IsErrorEnabled => _logger.IsErrorEnabled;
        public bool IsFatalEnabled => _logger.IsFatalEnabled;
        public bool IsInfoEnabled => _logger.IsInfoEnabled;
        public bool IsWarnEnabled => _logger.IsWarnEnabled;



        public ILogger CreateChildLogger(string loggerName) =>
            new NLogLogger(NLog.LogManager.GetLogger($"{_logger.Name}.{loggerName}"));

        public void Trace(string message)
        {
            throw new NotImplementedException();
        }

        public void Trace(Func<string> messageFactory)
        {
            throw new NotImplementedException();
        }

        public void Trace(string message, Exception exception)
        {
            throw new NotImplementedException();
        }

        public void TraceFormat(string format, params object[] args)
        {
            throw new NotImplementedException();
        }

        public void TraceFormat(Exception exception, string format, params object[] args)
        {
            throw new NotImplementedException();
        }

        public void TraceFormat(IFormatProvider formatProvider, string format, params object[] args)
        {
            throw new NotImplementedException();
        }

        public void TraceFormat(Exception exception, IFormatProvider formatProvider, string format, params object[] args)
        {
            throw new NotImplementedException();
        }

        public void Debug(string message) =>
            _logger.Debug(message);

        public void Debug(Func<string> messageFactory) =>
            _logger.Debug(messageFactory);

        public void Debug(string message, Exception exception) =>
            _logger.Debug(exception, message);

        public void DebugFormat(string format, params object[] args) =>
            _logger.Debug(string.Format(format, args));

        public void DebugFormat(Exception exception, string format, params object[] args) =>
            _logger.Debug(exception, string.Format(format, args));

        public void DebugFormat(IFormatProvider formatProvider, string format, params object[] args) =>
            _logger.Debug(formatProvider, format, args);

        public void DebugFormat(Exception exception, IFormatProvider formatProvider, string format, params object[] args) =>
            _logger.Debug(exception, formatProvider, format, args);



        public void Error(string message) =>
            _logger.Error(message);

        public void Error(Func<string> messageFactory) =>
            _logger.Error(messageFactory);

        public void Error(string message, Exception exception) =>
            _logger.Error(exception, message);

        public void ErrorFormat(string format, params object[] args) =>
            _logger.Error(string.Format(format, args));

        public void ErrorFormat(Exception exception, string format, params object[] args) =>
            _logger.Error(exception, string.Format(format, args));

        public void ErrorFormat(IFormatProvider formatProvider, string format, params object[] args) =>
            _logger.Error(formatProvider, format, args);

        public void ErrorFormat(Exception exception, IFormatProvider formatProvider, string format, params object[] args) =>
            _logger.Error(exception, formatProvider, format, args);



        public void Fatal(string message) =>
            _logger.Fatal(message);

        public void Fatal(Func<string> messageFactory) =>
            _logger.Fatal(messageFactory);

        public void Fatal(string message, Exception exception) =>
            _logger.Fatal(exception, message);

        public void FatalFormat(string format, params object[] args) =>
            _logger.Fatal(string.Format(format, args));

        public void FatalFormat(Exception exception, string format, params object[] args) =>
            _logger.Fatal(exception, string.Format(format, args));

        public void FatalFormat(IFormatProvider formatProvider, string format, params object[] args) =>
            _logger.Fatal(formatProvider, format, args);

        public void FatalFormat(Exception exception, IFormatProvider formatProvider, string format, params object[] args) =>
            _logger.Fatal(exception, formatProvider, format, args);



        public void Info(string message) =>
            _logger.Info(message);

        public void Info(Func<string> messageFactory) =>
            _logger.Info(messageFactory);

        public void Info(string message, Exception exception) =>
            _logger.Info(exception, message);

        public void InfoFormat(string format, params object[] args) =>
            _logger.Info(string.Format(format, args));

        public void InfoFormat(Exception exception, string format, params object[] args) =>
            _logger.Info(exception, string.Format(format, args));

        public void InfoFormat(IFormatProvider formatProvider, string format, params object[] args) =>
            _logger.Info(formatProvider, format, args);

        public void InfoFormat(Exception exception, IFormatProvider formatProvider, string format, params object[] args) =>
            _logger.Info(exception, formatProvider, format, args);



        public void Warn(string message) =>
            _logger.Warn(message);

        public void Warn(Func<string> messageFactory) =>
            _logger.Warn(messageFactory);

        public void Warn(string message, Exception exception) =>
            _logger.Warn(exception, message);

        public void WarnFormat(string format, params object[] args) =>
            _logger.Warn(string.Format(format, args));

        public void WarnFormat(Exception exception, string format, params object[] args) =>
            _logger.Warn(exception, string.Format(format, args));

        public void WarnFormat(IFormatProvider formatProvider, string format, params object[] args) =>
            _logger.Warn(formatProvider, format, args);

        public void WarnFormat(Exception exception, IFormatProvider formatProvider, string format, params object[] args) =>
            _logger.Warn(exception, formatProvider, format, args);

        public bool IsTraceEnabled { get; }
    }
}
